
import shutil

from pypinyin import lazy_pinyin

import base64
import os
from datetime import datetime


from fastapi import BackgroundTasks, Request, UploadFile
from common.config.env import UploadConfig
from common.exceptions.exception import ServiceException
from common.utils.upload_util import UploadUtil
from model.common.common_vo import CrudResponseModel, UploadResponseModel



class file_util:
    def create_file(path:str):
        try:
            os.makedirs(path, exist_ok=True)
        except FileExistsError:
            print("Folder already exists")


    def delete_file(path):
        if os.path.exists(path):
            shutil.rmtree(path)
        else:
            pass

    #删除指定文件的方法
    def delete_file_by_name(file_name):
        if os.path.exists(file_name):
            os.remove(file_name)
        else:
            pass
    #将判断一个变量是不是汉字 如果是 转换成拼音
    def is_chinese_char(char):
        return '\u4e00' <= char <= '\u9fff'

    def convert_to_pinyin(text):
        if all(file_util.is_chinese_char(char) for char in text):
            return ''.join(lazy_pinyin(text))
        else:
            return None

    @classmethod
    async def upload_for_editor(cls, request: Request, data: str, file_name: str):
        """
        专门用于编辑器的文件上传服务

        :param request: Request对象
        :param file_data: 包含Base64编码文件内容的字典
        :return: 上传结果
        """
        # 解码Base64编码的文件内容

        # 创建UploadFile对象
        try:
            file_content = base64.b64decode(data)
        except Exception as e:
            raise ServiceException(msg='Base64解码失败')
            # 提取文件名
        filename = file_name

        if not UploadUtil.check_file_extension_str(filename):
            raise ServiceException(msg='文件类型不合法')
        else:
            now = datetime.datetime.now()
            relative_path = f'upload/{now.strftime("%Y")}/{now.strftime("%m")}/{now.strftime("%d")}'
            dir_path = os.path.join(UploadConfig.UPLOAD_PATH, relative_path)
            try:
                os.makedirs(dir_path)
            except FileExistsError:
                pass
            # 生成新的文件名
            new_filename = f'{filename.rsplit(".", 1)[0]}_{datetime.datetime.now().strftime("%Y%m%d%H%M%S")}{UploadConfig.UPLOAD_MACHINE}{UploadUtil.generate_random_number()}.{filename.rsplit(".")[-1]}'
            filepath = os.path.join(dir_path, new_filename)
            # 写入文件内容
            with open(filepath, 'wb') as f:
                f.write(file_content)
            return CrudResponseModel(
                is_success=True,
                result=UploadResponseModel(
                    file_name=f'{UploadConfig.UPLOAD_PREFIX}/{relative_path}/{new_filename}',
                    new_file_name=new_filename,
                    original_filename=filename,
                    url=f'{request.base_url}{UploadConfig.UPLOAD_PREFIX[1:]}/{relative_path}/{new_filename}',
                ),
                msg='上传成功',
            )

    @classmethod
    async def upload_service(cls, request: Request, file: UploadFile):
        """
        通用上传service

        :param request: Request对象
        :param file: 上传文件对象
        :return: 上传结果
        """
        relative_path = f'upload/{datetime.now().strftime("%Y")}/{datetime.now().strftime("%m")}/{datetime.now().strftime("%d")}'
        dir_path = os.path.join(UploadConfig.UPLOAD_PATH, relative_path)
        try:
            os.makedirs(dir_path)
        except FileExistsError:
            pass
        filename = f'{file.filename.rsplit(".", 1)[0]}_{datetime.now().strftime("%Y%m%d%H%M%S")}{UploadConfig.UPLOAD_MACHINE}{UploadUtil.generate_random_number()}.{file.filename.rsplit(".")[-1]}'
        filepath = os.path.join(dir_path, filename)
        with open(filepath, 'wb') as f:
            # 流式写出大型文件，这里的10代表10MB
            for chunk in iter(lambda: file.file.read(1024 * 1024 * 10), b''):
                f.write(chunk)

        return CrudResponseModel(
            is_success=True,
            result=UploadResponseModel(
                file_name=f'{UploadConfig.UPLOAD_PREFIX}/{relative_path}/{filename}',
                new_file_name=filename,
                original_filename=file.filename,
                url=f'{request.base_url}{UploadConfig.UPLOAD_PREFIX[1:]}/{relative_path}/{filename}',
            ),
            msg='上传成功',
        )

    @classmethod
    async def download_services(cls,  file_name):
        """
        下载下载目录文件service

        :param background_tasks: 后台任务对象
        :param file_name: 下载的文件名称
        :param delete: 是否在下载完成后删除文件
        :return: 上传结果
        """
        filepath = os.path.join(UploadConfig.UPLOAD_PATH, file_name)

        if '..' in file_name:
            raise ServiceException(msg='文件名称不合法')
        elif not UploadUtil.check_file_exists(filepath):
            raise ServiceException(msg='文件不存在')
        else:

            return UploadUtil.generate_file(filepath)

    @classmethod
    async def download_resource_services(cls, resource: str):
        """
        下载上传目录文件service

        :param resource: 下载的文件名称
        :return: 上传结果
        """
        filepath = os.path.join(resource.replace(UploadConfig.UPLOAD_PREFIX, UploadConfig.UPLOAD_PATH))
        if not UploadUtil.check_file_exists(filepath):
            raise ServiceException(msg='文件不存在')
        else:
            return UploadUtil.generate_file(filepath)
